﻿// -------------------------------------------------------------------------
//    @FileName         :    NFTransCreateRole.cpp
//    @Author           :    Gao.Yi
//    @Date             :    2025-08-22
//    @Email			:    445267987@qq.com
//    @Module           :    NFTransCreateRole
//    @Desc             :
//
// -------------------------------------------------------------------------

#include "NFTransCreateRole.h"

#include "NFPacketSendUtil.h"
#include "NFSession.h"
#include "NFSessionUtil.h"
#include "NFTransGetAcc.h"
#include "proto_cs.pb.h"
#include "proto_cs_cmd.nanopb.h"
#include "proto_svr_common.nanopb.h"
#include "proto_svr_onlinesvr.pb.h"
#include "ZoneMergeDescEx.h"
#include "NFServerComm/NFServerCommon/NFIServerMessageModule.h"

typedef enum
{
    EN_CREATEROLE_INIT = 0,
    EN_CREATEROLE_GET_ROLELIST = 1,
    EN_CREATEROLE_TRY_CREATEROLE = 2,
    EN_CREATEROLE_FIN_OK = 3,
} ETransGetRoleListState;

NFTransCreateRole::NFTransCreateRole()
{
    if (EN_OBJ_MODE_INIT == NFShmMgr::Instance()->GetCreateMode())
    {
        CreateInit();
    }
    else
    {
        ResumeInit();
    }
}

NFTransCreateRole::~NFTransCreateRole()
{
}

int NFTransCreateRole::CreateInit()
{
    SetState(EN_CREATEROLE_INIT);
    return 0;
}

int NFTransCreateRole::ResumeInit()
{
    return 0;
}

int NFTransCreateRole::HandleCSMsgReq(const google::protobuf::Message* pCSMsgReq)
{
    CHECK_NULL(0, pCSMsgReq);
    CHECK_EXPR(GetState() == EN_CREATEROLE_INIT, proto_ff::ERR_CODE_SYSTEM_OBJSTATUS_INVALID, "invalid tran state! {}", DebugString());
    NFSession *pSession = GetClientSession();
    CHECK_NULL(0, pSession);

    const proto_ff::Proto_CSReq *pCSReq = (proto_ff::Proto_CSReq *) pCSMsgReq;
    m_stCreateRoleReq.FromPb(pCSReq->create_role_req());

    proto_ff::tbRoleList tbRoleList;
    tbRoleList.set_uin(m_uin);
    tbRoleList.set_world_id(m_zoneId);
    tbRoleList.set_world_type(pSession->GetPlatformType());
    GetCacheDataSingleReq<NFTransGetAcc>(m_uin, 0, tbRoleList, E_TABLE_ROLE_LIST);
    SetState(EN_CREATEROLE_GET_ROLELIST);

    return 0;
}

int NFTransCreateRole::HandleDispSvrRes(uint32_t nMsgId, const NFDataPackage& packet, uint32_t reqTransId, uint32_t rspTransId)
{
    int iRetCode = 0;
    if (nMsgId == E_ONLINE2ZONE_CREATEROLE_RES)
    {
        iRetCode = OnHandleOnlineCreateRoleRes(nMsgId, packet, reqTransId, rspTransId);
        CHECK_ERR(m_uin, iRetCode, "OnHandleOnlineCreateRoleRes failed, TransInfo:{}", DebugString());
    }
    else
    {
        CHECK_ERR(m_uin, -1, "HandleDispSvrRes failed, unknown msgId: {}, TransInfo:{}", nMsgId, DebugString());
    }

    return 0;
}

int NFTransCreateRole::GetCacheDataRes(int ullId, int iTableId, int iReason, int32_t errCode, google::protobuf::Message* pMessage)
{
    CHECK_EXPR(GetState() == EN_CREATEROLE_GET_ROLELIST, proto_ff::ERR_CODE_SYSTEM_OBJSTATUS_INVALID, "invalid tran state! {}", DebugString());
    NFSession* pSession = GetClientSession();
    CHECK_EXPR(pSession, -3, "GetClientSession Failed TransInfo:{}", DebugString());

    if (errCode == ERR_CODE_STORESVR_ERRCODE_SELECT_EMPTY)
    {
        bool bCanRegister;
        int iRetCode = NFSessionUtil::IsRegisterLimit(pSession, bCanRegister);
        CHECK_ERR(m_iClientSessionID, iRetCode, "IsRegisterLimit failed, TransInfo:{}", DebugString());
        if (!bCanRegister)
        {
            return ERR_CODE_FORBID_REGIST_ACCOUNT;
        }
    }
    else if (errCode != 0)
    {
        LOG_ERR(ullId, errCode, "GetCacheDataRes failed, errCode: {}", errCode);
        return errCode;
    }

    proto_ff::Proto_Zone2OnLineCreateRoleReq stCreateRoleReq;
    stCreateRoleReq.set_player_uin(pSession->GetUIN());
    stCreateRoleReq.set_platform_type(pSession->GetPlatformType());
    stCreateRoleReq.set_zone_id(pSession->GetZoneID());
    m_stCreateRoleReq.ToPb(stCreateRoleReq.mutable_create_role_req());
    stCreateRoleReq.set_account_id(pSession->GetAccountID());
    stCreateRoleReq.set_reg_channel(pSession->GetClientInfo()->reg_channel_str.ToString());
    stCreateRoleReq.set_login_channel(pSession->GetClientInfo()->login_channel_str.ToString());

    FindModule<NFIServerMessageModule>()->SendTransToOnlineServer(NF_ST_LOGIC_SERVER, ZoneMergeDescEx::Instance()->GetMergeZoneId(pSession->GetZoneID()), E_ZONE2ONLINE_CREATEROLE_REQ, stCreateRoleReq, pSession->GetUIN(), GetGlobalId(), 0);

    SetState(EN_CREATEROLE_TRY_CREATEROLE);
    return 0;
}

int NFTransCreateRole::OnTransFinished(int iRunLogicRetCode)
{
    if (iRunLogicRetCode != 0)
    {
        NFPacketSendUtil::SendErrToClient(GetClientSession(), proto_ff::E_CS_CREATE_ROLE_REQ, (proto_ff::Proto_CS_ErrorCode) iRunLogicRetCode);
    }
    return 0;
}

int NFTransCreateRole::OnHandleOnlineCreateRoleRes(uint32_t nMsgId, const NFDataPackage& packet, uint32_t reqTransId, uint32_t rspTransId)
{
    proto_ff::Proto_OnLine2ZoneCreateRoleRes res;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, res);

    CHECK_EXPR(GetState() == EN_CREATEROLE_TRY_CREATEROLE, proto_ff::ERR_CODE_SYSTEM_OBJSTATUS_INVALID, "invalid tran state! {}", DebugString());

    NFSession *pSession = GetClientSession();
    CHECK_NULL(0, pSession);

    if (pSession->GetZoneID() != res.zone_id() || pSession->GetUIN() != res.player_uin())
    {
        LOG_ERR(pSession->GetUIN(), -1, "OnHandleOnlineCreateRoleRes failed, zoneId or uin not match! TransInfo:{}", DebugString());
        return -1;
    }

    proto_ff::Proto_CSRsp oCSRsp;
    proto_ff::Proto_CSCreateRoleRsp *pCreateRoleRsp = oCSRsp.mutable_create_role_rsp();

    pCreateRoleRsp->set_result(res.result());
    for (int i = 0; i < res.role_list_size(); ++i)
    {
        proto_ff::RoleOne *pRoleOne = pCreateRoleRsp->add_role_list();
        pRoleOne->CopyFrom(res.role_list(i));
    }

    NFPacketSendUtil::SendToClient(pSession, proto_ff::E_CS_CREATE_ROLE_RSP, &oCSRsp);
    SetFinished(0);
    return 0;
}

